<template>
  <div
    class="container"
    v-loading="loading"
    element-loading-text="加载中"
    element-loading-background="rgba(122, 122, 122, 0.8)"
  >
    <div id="map" class="map__x"></div>
    <el-button @click="openDrawer" class="configBtn">配置</el-button>
    <el-drawer
      v-model="configDrawerShow"
      title="配置"
      direction="rtl"
      :close-on-click-modal="false"
    >
      <div class="demo-drawer__content">
        <el-form :model="form">
          <!-- <el-form-item label="平台提供的 APPKey">
            <el-input v-model="form.appkey" autocomplete="off" />
          </el-form-item>
          <el-form-item label="平台提供的 APPSecret">
            <el-input v-model="form.secret" autocomplete="off" />
          </el-form-item>
          <el-form-item label="平台IP 地址">
            <el-input v-model="form.ip" autocomplete="off" />
          </el-form-item>
          <el-form-item label="平台端口">
            <el-input v-model="form.port" autocomplete="off" />
          </el-form-item> -->
          <!-- <el-form-item label="监控点编号">
            <el-input v-model="form.cameraIndexCode" autocomplete="off" />
          </el-form-item> -->
          <el-form-item label="监控点">
            <el-select
              v-model="form.cameraIndexCode"
              placeholder="Select"
              size="large"
            >
              <el-option
                v-for="item in cameraIndexCodeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-divider />
          <el-form-item label="地图">
            <el-input v-model="form.mapUrl" autocomplete="off" />
          </el-form-item>
          <el-form-item label="坐标系">
            <el-input v-model="form.projection" autocomplete="off" />
          </el-form-item>
          <el-form-item label="点的经度">
            <el-input v-model="form.lng" autocomplete="off" />
          </el-form-item>
          <el-form-item label="点的纬度">
            <el-input v-model="form.lat" autocomplete="off" />
          </el-form-item>
        </el-form>
        <div class="demo-drawer__footer">
          <el-button type="primary" @click="onSave"> 保存 </el-button>
        </div>
      </div>
    </el-drawer>

    <el-dialog
      v-model="dialogVideoVisible"
      title="视频监控"
      width="730px"
      @opened="onPlayer"
      @close="onStopPlayer"
      :destroy-on-close="true"
    >
      <video ref="myPlayer" class="video-js">
        your browser does not support the video tag
      </video>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, reactive, nextTick } from "vue"; // vue相关方法
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";
import Feature from "ol/Feature";
import { MVT } from "ol/format";
import {
  TileSuperMapRest,
  VectorTileSuperMapRest,
  MapboxStyles,
} from "@supermap/iclient-ol";
import VectorSource from "ol/source/Vector";
import Point from "ol/geom/Point";
import { Style, Circle, Fill, Icon, Stroke } from "ol/style";
import { Map, View, Overlay } from "ol";
import "ol/ol.css"; // 地图样式
import videojs from "video.js";
import "video.js/dist/video-js.min.css";
import "videojs-flvjs-es6";
import "videojs-flash";
import SWF_URL from "videojs-swf/dist/video-js.swf";
import request from "@/api/request";
import axios from "axios";
import {
  getDataByUrl,
  getFeaturesObjByGeometry,
  getVectorStyle,
  loadVector,
} from "./loadVector.ts";
// import "video.js/dist/lang/zh-CN.js";

onMounted(() => {
  initMap();
});

let map: Map;
let tLayer: TileLayer<any>;
let vLayer: VectorLayer<any>;
let pointGeometry: Point;
let player: any;
let sources: { type: string; src: string }[] = [];
const loading = ref(true);
const dialogVideoVisible = ref(false);
const configDrawerShow = ref(false);
const config = reactive({
  // appkey: "27576186",
  // ip: "116.63.194.174",
  // secret: "vhjcqyJV4n8jaVPu6pKf",
  // cameraIndexCode: "e5d6bf643a624532850899b4fb69f3ac",
  // port: 443,
  cameraIndexCode: "",
});

const mapConfig = reactive({
  url: "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World",
  //   url: 'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China',
  projection: "EPSG:4326",
  lng: 114.064839,
  lat: 22.548857,

  vectorUrl:
    "http://support.supermap.com.cn:8090/iserver/services/data-DynamicData/rest/data/datasources/DynamicData/datasets/Point",
});

const form = reactive({
  appkey: "",
  ip: "",
  secret: "",
  cameraIndexCode: "",
  port: 443,
  mapUrl: "",
  projection: "",
  lng: 0,
  lat: 0,
});
const myPlayer = ref();

const cameraIndexCodeOptions = ref([]);

initCameraData();

function initCameraData() {
  loading.value = true;
  request
    .post("/api/isc/getCameras")
    .then((res) => {
      const data = JSON.parse(res.data.data);
      cameraIndexCodeOptions.value = data.data.list.map((item) => {
        return {
          label: item.cameraName,
          value: item.cameraIndexCode,
        };
      });
      const camera = cameraIndexCodeOptions.value;
      console.log(camera, "camera");
      if (camera && camera.length) {
        config.cameraIndexCode = camera[0].value;
        form.cameraIndexCode = camera[0].value;
        getSources();
      }
    })
    .catch((err) => {
      console.error(err);
    })
    .finally(() => {
      loading.value = false;
    });
}

function getSources() {
  loading.value = true;
  Promise.allSettled([getSource("rtsp"), getSource("hls"), getSource("rtmp")])
    .then((res) => {
      sources = [];
      for (let item of res) {
        if (item.status == "fulfilled") {
          sources.push(item.value);
        }
      }
    })
    .catch((err) => {
      console.error(err);
    })
    .finally(() => {
      loading.value = false;
    });
}

const obj = {
  hls: "application/x-mpegURL",
  rtmp: "rtmp/flv",
  rtsp: "rtsp",
  flv: "video/x-flv",
};

function getSource(protocol: "hls" | "rtsp" | "rtmp") {
  return request
    .post("/api/isc/getPreviewURLs", {
      cameraIndexCode: config.cameraIndexCode,
      protocol,
      streamType: 0,
      transmode: 1,
    })
    .then((res) => {
      const data = JSON.parse(res.data.data);
      return {
        type: obj[protocol],
        src: data.data.url,
      };
    });
}

function onPlayer(src: string) {
  console.log(sources, "sources");
  player = videojs(
    myPlayer.value,
    {
      autoplay: "muted", // 自动静音播放
      controls: true, // 显示控制器
      techOrder: ["html5", "flvjs", "flash"], // 定义Video.js技术首选的顺序 这里的顺序一定要 'flvjs' 在 'flash' 前面，要不然 flv 格式的就无法播放了
      flash: {
        hls: { withCredentials: false },
        swf: SWF_URL, // 引入静态文件swf
      },
      flvjs: {
        mediaDataSource: {
          cors: true,
          withCredentials: false,
        },
      },
      disablePictureInPicture: true, // 禁用画中画功能
      language: "zh-CN", // 语言设置
      sources,
      notSupportedMessage: "此视频暂无法播放",
    },
    () => {}
  );
}

function onStopPlayer() {
  player.dispose();
}

function openDrawer() {
  configDrawerShow.value = true;
  form.appkey = config.appkey;
  form.ip = config.ip;
  form.secret = config.secret;
  form.cameraIndexCode = config.cameraIndexCode;
  form.port = config.port;
  form.mapUrl = mapConfig.url;
  form.projection = mapConfig.projection;
  form.lng = mapConfig.lng;
  form.lat = mapConfig.lat;
}

function onSave() {
  if (config.cameraIndexCode != form.cameraIndexCode) {
    config.cameraIndexCode = form.cameraIndexCode;
    getSources();
  }
  configDrawerShow.value = false;
  if (form.mapUrl != mapConfig.url || form.projection != mapConfig.projection) {
    mapConfig.url = form.mapUrl;
    mapConfig.projection = form.projection;
    if (tLayer) {
      tLayer.setSource(createSource());
    }
  }
  if (form.lng != mapConfig.lng || form.lat != mapConfig.lat) {
    mapConfig.lng = form.lng;
    mapConfig.lat = form.lat;
    if (pointGeometry) {
      pointGeometry.setCoordinates([mapConfig.lng, mapConfig.lat]);
    }
  }
}

function createSource() {
  return new TileSuperMapRest({
    url: mapConfig.url,
    projection: mapConfig.projection,
  });
}

function initMap() {
  map = new Map({
    target: "map", // 绑定html元素
    view: new View({
      // 地图视图
      projection: "EPSG:4326", // 坐标系，有EPSG:4326和EPSG:3857
      center: [mapConfig.lng, mapConfig.lat], // 深圳坐标
      zoom: 5, // 地图缩放级别（打开页面时默认级别）
    }),
  });

  tLayer = new TileLayer({
    source: createSource(),
  });

  map.addLayer(tLayer);

  pointGeometry = new Point([mapConfig.lng, mapConfig.lat]);

  const vectorSource = new VectorSource({
    wrapX: false,
  });
  const resultLayer = new VectorLayer({
    source: vectorSource,
  });
  map.addLayer(resultLayer);

  const { datasetName, baseUrl } = getDataByUrl(mapConfig.vectorUrl);
  getFeaturesObjByGeometry(baseUrl, datasetName).then((featuresObj) => {
    const style = getVectorStyle();
    loadVector(vectorSource, featuresObj, style);
  });

  map.on("click", function (e) {
    var feature = map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
      return feature;
    });
    if (feature) {
      // console.log(feature.getProperties(),'feature.getPropertie')
      dialogVideoVisible.value = true;
    }
  });
}
</script>

<style lang="scss" scoped>
.container {
  position: relative;
  width: 100%;
  height: 100%;
}

.configBtn {
  position: absolute;
  top: 10px;
  right: 10px;
}

.closeBtn {
  position: absolute;
  top: 10px;
  right: 100px;
}
.video-js {
  width: 700px;
  height: 400px;
}
</style>